package exercises;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 苏李涛
 * Date: 2024-07-12
 * Time: 13:44
 */

/**
 * 对于一个链表，请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法，判断其是否为回文结构。
 *
 * 给定一个链表的头指针A，请返回一个bool值，代表其是否为回文结构。保证链表长度小于等于900。
 *
 * 测试样例：
 * 1->2->2->1
 * 返回：true
 */

/**
 * 方法：
 * 1.找到中间节点
 * 2.翻转链表
 * 3.判断回文
 */

public class Exercise1 {

    public class ListNode {
        int val;
        ListNode next = null;

        ListNode(int val) {
            this.val = val;
        }
    }

    public boolean chkPalindrome(ListNode A) {
        if (A == null) {
            return true;
        }

        // write code here
        ListNode fast = A;
        ListNode slow = A;

        //1.找到中间节点
        while (fast != null && fast.next != null) {
            fast = fast.next.next;
            slow = slow.next;
        }


        //2.翻转链表
        ListNode cur = slow.next;
        while (cur != null) {
            ListNode curN = cur.next;
            cur.next = slow;
            slow = cur;
            cur = curN;
        }


        //3.判断回文
        //让head往后走，slow往前走直到；head.val==slow.val
        //注意：回文时会有偶数情况下，A的下一个节点是slow节点，并且两个节点的val相等。这个时候就要直接返回ture
        while (A != slow) {
            if (A.val != slow.val) {
                return false;
            }
            //到这里A.val == slow.val

            //A.val == slow.val前提下，偶数情况下，A的下一个节点是slow节点，并且两个节点的val相等。这个时候就要直接返回ture
            if (A.next == slow) {
                return true;
            }

            A = A.next;
            slow = slow.next;
        }
        return true;
    }

}
